/*
 * Copyright 2010 Electronic Business Systems Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package gr.ebs.gssdroid.activities;

import gr.ebs.gssdroid.GssDroidApplication;
import gr.ebs.gssdroid.R;
import gr.ebs.gssdroid.async.GssAsyncTask;
import gr.ebs.gssdroid.async.TaskResult;
import gr.ebs.gssdroid.http.GssHttpCommands;
import gr.ebs.gssdroid.http.GssHttpException;
import gr.ebs.gssdroid.http.SystemErrorException;
import gr.ebs.gssdroid.resource.FileResource;
import gr.ebs.gssdroid.resource.PermissionHolder;
import gr.ebs.gssdroid.resource.RestResource;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class GssVersions extends Activity {
	FileResource res;
	public ProgressDialog myprogress;
	List<FileResource> versions = new ArrayList<FileResource>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		res = (FileResource) getIntent().getExtras().get("resource");
		getFileTask().execute(res.getUri());

	}

	private void createFileLayout() {
		((TextView) findViewById(R.id.textFolderName))
				.setText(((FileResource) res).getName());
		LayoutInflater layoutInflater = LayoutInflater.from(GssVersions.this);
		((CheckBox) findViewById(R.id.versioned))
				.setChecked(((FileResource) res).isVersioned());
		((CheckBox) findViewById(R.id.versioned))
				.setOnCheckedChangeListener(new OnCheckedChangeListener() {

					@Override
					public void onCheckedChanged(CompoundButton buttonView,
							boolean isChecked) {
						((FileResource) res).setVersioned(isChecked);

						try {
							toggleVersioned();
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});

		rebuildVersionList();

	}

	protected void toggleVersioned() throws JSONException {
		FileResource folder = (FileResource) res;
		Set<PermissionHolder> perms = folder.getPermissions();
		JSONObject json = new JSONObject();
		json.put("versioned", folder.isVersioned());
		// new
		// GssHttpCommands(getDroidApplication().getUserDetails()).updateFile(folder.getUri(),
		// json.toString());
		toggleVersionTask().execute(folder.getUri(), json.toString());

	}

	RestResource getRestResource() {
		return res;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
			onBackPressed();
			return true;
		}

		return super.onKeyDown(keyCode, event);
	}

	public void onBackPressed() {
		// TODO Auto-generated method stub
		setResult(RESULT_CANCELED);
		// equivalent of 'return'
		finish();
		// super.onBackPressed();
	}

	public void returnToCaller(Bundle bundle) {
		// sets the result for the calling activity
		setResult(RESULT_OK);
		// equivalent of 'return'
		finish();
	}

	protected void showErrorDialog(String title, String message) {
		AlertDialog alertDialogn = new AlertDialog.Builder(this).create();
		alertDialogn.setTitle(title);
		alertDialogn.setMessage(message);
		alertDialogn.setButton("Continue",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
		alertDialogn.setCancelable(true);
		alertDialogn.show();
	}

	protected GssAsyncTask toggleVersionTask() {
		GssAsyncTask getFolderTask = new GssAsyncTask(getDroidApplication()
				.getUserDetails()) {
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				myprogress = ProgressDialog.show(GssVersions.this, "Updating",
						"Please Wait", true, false);
			}

			@Override
			protected RestResource doExecution(String[] params)
					throws Exception {
				new GssHttpCommands(getDroidApplication().getUserDetails())
						.updateFile(params[0], params[1]);
				return null;
			}

			@Override
			protected void onPostExecute(TaskResult result) {
				myprogress.hide();
				if (result.getException() == null) {
					getFileTask().execute(res.getUri());
				} else if (result.getException() != null)
					handleRestException("TRASH", result.getException());
				super.onPostExecute(result);
			}

		};
		return getFolderTask;
	}

	protected GssAsyncTask getFileTask() {
		GssAsyncTask getFolderTask = new GssAsyncTask(getDroidApplication()
				.getUserDetails()) {
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				myprogress = ProgressDialog.show(GssVersions.this,
						"Fetching Data", "Please Wait", true, false);
			}

			@Override
			protected RestResource doExecution(String[] params)
					throws Exception {
				FileResource file = new GssHttpCommands(getDroidApplication()
						.getUserDetails()).getFileResource(params[0]);
				getVersions().clear();
				if (file.isVersioned()) {
					for (int i = 1; i <= file.getVersion(); i++) {
						String pathn = file.getUri() + "?version=" + i;
						try {
							FileResource v = new GssHttpCommands(
									getDroidApplication().getUserDetails())
									.getFileResource(pathn);
							if (v != null)
								getVersions().add(v);
						} catch (Exception ex) {
						}
						// getVersionsTask().execute(pathn);
					}
				}
				return file;
			}

			@Override
			protected void onPostExecute(TaskResult result) {
				myprogress.hide();
				if (result.getResource() != null) {
					res = (FileResource) result.getResource();

					setContentView(R.layout.versions);
					createFileLayout();
				} else if (result.getException() != null)
					handleRestException("TRASH", result.getException());
				super.onPostExecute(result);
			}

		};
		return getFolderTask;
	}

	protected GssAsyncTask getVersionsTask() {
		GssAsyncTask getFolderTask = new GssAsyncTask(getDroidApplication()
				.getUserDetails()) {
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				// myprogress = ProgressDialog.show(GssVersions.this,
				// "Fetching Data", "Please Wait", true, false);
			}

			@Override
			protected RestResource doExecution(String[] params)
					throws Exception {
				return new GssHttpCommands(getDroidApplication()
						.getUserDetails()).getFileResource(params[0]);
			}

			@Override
			protected void onPostExecute(TaskResult result) {
				// myprogress.hide();
				if (result.getResource() != null) {
					FileResource vres = (FileResource) result.getResource();
					getVersions().add(vres);

				} // else if (result.getException() != null)
					// handleRestException("TRASH", result.getException());
				super.onPostExecute(result);
			}

		};
		return getFolderTask;
	}

	public List<FileResource> getVersions() {
		return versions;
	}

	protected void handleRestException(String type, Throwable e) {
		String errorMessage = "";
		if (e instanceof SystemErrorException)
			errorMessage = e.getMessage();
		else if (e instanceof GssHttpException)
			if (((GssHttpException) e).getStatusCode() > 0)
				errorMessage = "Status Code:"
						+ ((GssHttpException) e).getStatusCode() + "\n"
						+ e.getMessage();
		AlertDialog alertDialogn = new AlertDialog.Builder(this).create();
		alertDialogn.setTitle("An error occured");
		alertDialogn.setMessage(errorMessage);
		alertDialogn.setButton("Continue",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
		alertDialogn.setCancelable(true);
		alertDialogn.show();

	}

	private void rebuildVersionList() {
		LayoutInflater layoutInflater = LayoutInflater.from(GssVersions.this);
		final LinearLayout properties = (LinearLayout) findViewById(R.id.versionsList);
		if (properties.getChildCount() > 0)
			properties.removeViews(0, properties.getChildCount());
		properties.removeAllViews();
		Iterator<FileResource> it;
		Collections.reverse(versions);
		it = versions.iterator();
		int i = 0;
		while (it.hasNext()) {
			final FileResource perm = it.next();
			final View v = layoutInflater.inflate(R.layout.versionsrow, null);
			populateVersionList(perm, v, properties, i);
			i++;
		}
	}

	private void populateVersionList(final FileResource perm, final View v,
			final LinearLayout properties, int i) {

		properties.addView(v, i);

		((TextView) v.findViewById(R.id.versionName)).setText("Version: "
				+ perm.getVersion());
		((TextView) v.findViewById(R.id.versionSize)).setText("Size: "
				+ perm.getFileSizeAsString());
		((TextView) v.findViewById(R.id.versionCreation)).setText("Created: "
				+ perm.getCreationDate());
		((TextView) v.findViewById(R.id.versionModified)).setText("Modified: "
				+ perm.getModificationDate());
		if(versions.size()==1){
			//((Button) v.findViewById(R.id.vremove)).setVisibility(View.INVISIBLE);
			((Button) v.findViewById(R.id.vrestore)).setVisibility(View.INVISIBLE);
		}
		/*
		((Button) v.findViewById(R.id.vremove))
				.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v1) {
						Log.d("PERMS", perm.getUri());
						try {
							new GssHttpCommands(getDroidApplication()
									.getUserDetails()).deleteFolder(perm.getUri()+"?version="+perm.getVersion());
						} catch (SystemErrorException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (GssHttpException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						getFileTask().execute(res.getUri());
						//properties.removeView(v);

					}
				});*/
		((Button) v.findViewById(R.id.vrestore))
		.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v1) {
				Log.d("PERMS", perm.getUri());
					geRestoreVersionTask().execute(perm.getUri()+"?restoreVersion="+perm.getVersion());

			}
		});
		((Button) v.findViewById(R.id.vdownload))
		.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v1) {
				
				getDownloadTask().execute(perm.getUri()+"?version="+perm.getVersion());
				//properties.removeView(v);

			}
		});
	}

	public GssDroidApplication getDroidApplication() {
		return (GssDroidApplication) getApplicationContext();
	}
	public GssAsyncTask geRestoreVersionTask() {
		GssAsyncTask getFolderTask = new GssAsyncTask(getDroidApplication()
				.getUserDetails()) {
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				myprogress = ProgressDialog.show(GssVersions.this, "Restoring Version", "Please Wait", false, false);
				
			}

			@Override
			protected RestResource doExecution(String[] params) throws Exception {
				String path = new GssHttpCommands(getDroidApplication()
						.getUserDetails()).restoreVersion(params[0], this);
				
				return new RestResource(path) {

					@Override
					public String getLastModifiedSince() {
						// TODO Auto-generated method stub
						return null;
					}

					@Override
					public void createFromJSON(String text) throws JSONException {
						// TODO Auto-generated method stub

					}
				};
			}
			
			
			@Override
			protected void onProgressUpdate(Integer... values) {
				//myprogress.setTitle(values[0]+"% complete");
				myprogress.setMessage(values[0]+"% complete");
				super.onProgressUpdate(values);
			}

			@Override
			protected void onPostExecute(TaskResult result) {
				myprogress.hide();
				if (result.getException() != null)
					handleRestException("Restore", result.getException());
				else {
					getFileTask().execute(res.getUri());
				}
				super.onPostExecute(result);
			}
		};
		return getFolderTask;
	}
	
	public GssAsyncTask getDownloadTask() {
		GssAsyncTask getFolderTask = new GssAsyncTask(getDroidApplication()
				.getUserDetails()) {
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				Toast.makeText(GssVersions.this, "Downloading File to /sdcard/gss/", Toast.LENGTH_SHORT).show();
				myprogress = ProgressDialog.show(GssVersions.this, "File Download", "Please Wait", false, false);
				
			}

			@Override
			protected RestResource doExecution(String[] params) throws Exception {
				String path = new GssHttpCommands(getDroidApplication()
						.getUserDetails()).downloadFileCommand(params[0], this);
				
				return new RestResource(path) {

					@Override
					public String getLastModifiedSince() {
						// TODO Auto-generated method stub
						return null;
					}

					@Override
					public void createFromJSON(String text) throws JSONException {
						// TODO Auto-generated method stub

					}
				};
			}
			
			
			@Override
			protected void onProgressUpdate(Integer... values) {
				//myprogress.setTitle(values[0]+"% complete");
				myprogress.setMessage(values[0]+"% complete");
				super.onProgressUpdate(values);
			}

			@Override
			protected void onPostExecute(TaskResult result) {
				myprogress.hide();
				if (result.getException() != null)
					handleRestException("DOWNLOAD", result.getException());
				else {
					NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
					long SIMPL = System.currentTimeMillis();
					final Notification notifyDetails = new Notification(R.drawable.icon, "", SIMPL);
					Context context = getApplicationContext();
					CharSequence contentTitle = "File " + new File(result.getResource().getUri()).getName() + " downloaded...";
					CharSequence contentText = "Open file by clicking me";
					Intent notifyIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.fromFile(new File(result.getResource().getUri())));
					
					String ext = MimeTypeMap.getSingleton().getFileExtensionFromUrl(result.getResource().getUri());
					String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);

					if (mime != null)
						notifyIntent.setDataAndType(Uri.fromFile(new File(result.getResource().getUri())), mime);
					
					PendingIntent intent = PendingIntent.getActivity(context, 0, notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

					notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intent);
					notifyDetails.flags|=Notification.FLAG_AUTO_CANCEL;
					notificationManager.notify(100, notifyDetails);
					
					Intent viewIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.fromFile(new File(result.getResource().getUri())));
					String extv = MimeTypeMap.getSingleton().getFileExtensionFromUrl(result.getResource().getUri());
					String mimev = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
					if (mimev != null)
						viewIntent.setDataAndType(Uri.fromFile(new File(result.getResource().getUri())), mime);
					startActivity(viewIntent);

				}
				super.onPostExecute(result);
			}
		};
		return getFolderTask;
	}
}
